{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-05-19T10:32:37.111419Z",
     "start_time": "2025-05-19T10:32:35.793196Z"
    }
   },
   "source": "import torch",
   "outputs": [],
   "execution_count": 1
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-19T10:32:37.236643Z",
     "start_time": "2025-05-19T10:32:37.233495Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class MyModel(torch.nn.Module):\n",
    "    def __init__(self):\n",
    "        super(MyModel, self).__init__()\n",
    "        self.linear1 = torch.nn.Linear(3, 3, bias=False)\n",
    "        self.relu = torch.nn.ReLU()\n",
    "        self.linear2 = torch.nn.Linear(3, 1, bias=False)\n",
    "\n",
    "    def forward(self, x):\n",
    "        return self.linear2(self.relu(self.linear1(x)))"
   ],
   "id": "38dc2fdd3940674e",
   "outputs": [],
   "execution_count": 2
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-19T10:32:37.246846Z",
     "start_time": "2025-05-19T10:32:37.241709Z"
    }
   },
   "cell_type": "code",
   "source": [
    "weights = torch.tensor([[1.1], [2.2], [3.3]])\n",
    "torch.manual_seed(123)\n",
    "training_features = torch.randn(12000, 3)\n",
    "training_labels = training_features @ weights\n",
    "\n",
    "test_feature = torch.randn(1000, 3)\n",
    "test_labels = test_feature @ weights"
   ],
   "id": "84fa32fa952ef65b",
   "outputs": [],
   "execution_count": 3
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-19T10:32:38.183794Z",
     "start_time": "2025-05-19T10:32:37.266579Z"
    }
   },
   "cell_type": "code",
   "source": [
    "model = MyModel()\n",
    "optimizer = torch.optim.Adam(model.parameters(), lr=0.1)\n",
    "\n",
    "for i in range(100):\n",
    "    pred = model(training_features)\n",
    "    loss = torch.nn.functional.mse_loss(pred, training_labels)\n",
    "    loss.backward()\n",
    "    optimizer.step()\n",
    "    optimizer.zero_grad()"
   ],
   "id": "7ecf6daa512bec7",
   "outputs": [],
   "execution_count": 4
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-19T10:33:11.512550Z",
     "start_time": "2025-05-19T10:33:11.509349Z"
    }
   },
   "cell_type": "code",
   "source": [
    "model.eval()\n",
    "with torch.no_grad():\n",
    "    pred = model(test_feature)\n",
    "    loss = torch.nn.functional.mse_loss(pred, test_labels)\n",
    "    print(f'float32 model testing loss: {loss.item():3f}')"
   ],
   "id": "3d249553d7c9449b",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "float32 model testing loss: 0.000538\n"
     ]
    }
   ],
   "execution_count": 10
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-19T10:32:38.240671Z",
     "start_time": "2025-05-19T10:32:38.235613Z"
    }
   },
   "cell_type": "code",
   "source": [
    "model_int8 = torch.ao.quantization.quantize_dynamic(model, {torch.nn.Linear}, dtype=torch.qint8)\n",
    "with torch.no_grad():\n",
    "    pred = model(test_feature)\n",
    "    loss = torch.nn.functional.mse_loss(pred, test_labels)\n",
    "    print(f'int8 model testing loss: {loss.item():3f}')"
   ],
   "id": "ef7a4e85a40250df",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "int8 model testing loss: 0.000538\n"
     ]
    }
   ],
   "execution_count": 6
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-19T10:33:50.189001Z",
     "start_time": "2025-05-19T10:33:50.184499Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(\"float32 model linear1 parameter:\", model.linear1.weight)\n",
    "print(\"int8 model linear1 parameter:\", torch.int_repr(model_int8.linear1.weight()))\n",
    "print(\"int8 model linear2 parameter:\", torch.int_repr(model_int8.linear2.weight()))\n",
    "print(\"int8 model linear1 parameter:\", model_int8.linear1.weight())"
   ],
   "id": "c875352760ff5852",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "float32 model linear1 parameter: Parameter containing:\n",
      "tensor([[-0.4193, -0.9358, -1.5471],\n",
      "        [ 0.7439,  1.5075,  2.2410],\n",
      "        [-0.6156, -1.1403, -1.5620]], requires_grad=True)\n",
      "int8 model linear1 parameter: tensor([[-24, -53, -88],\n",
      "        [ 42,  86, 127],\n",
      "        [-35, -65, -89]], dtype=torch.int8)\n",
      "int8 model linear2 parameter: tensor([[-92, 127, -91]], dtype=torch.int8)\n",
      "int8 model linear1 parameter: tensor([[-0.4218, -0.9316, -1.5467],\n",
      "        [ 0.7382,  1.5116,  2.2322],\n",
      "        [-0.6152, -1.1425, -1.5643]], size=(3, 3), dtype=torch.qint8,\n",
      "       quantization_scheme=torch.per_tensor_affine, scale=0.017576610669493675,\n",
      "       zero_point=0)\n"
     ]
    }
   ],
   "execution_count": 12
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-19T10:32:38.301494Z",
     "start_time": "2025-05-19T10:32:38.299495Z"
    }
   },
   "cell_type": "code",
   "source": "",
   "id": "de39521bc5334be4",
   "outputs": [],
   "execution_count": null
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
